<template>
  <div :id="`wft-senior-form-${curComp.id}`" @dblclick.stop="seniorFormDblclick" @mousedown="deactivatedFormItem" @contextmenu="seniorFormContextHandler" :class="['wft-senior-form', { 'wft-loop-glowing': curComp.config.isEnchase }]">
    <van-form :label-width="attrs.labelWidth" :label-align="attrs.labelAlign" :disabled="curComp.config.disabled">
      <VueDraggable :animation="200" v-model="curComp.children">
        <div v-for="(comp, index) in curComp.children" :key="comp.id" :class="['form-item', { activeItem: comp.config.isActive }]" :style="{ 'pointer-events': curComp.config.isEnchase ? 'auto' : 'none' }" @mousedown.stop="formItemClick(comp)">
          <component
            :is="`${comp.compKey}Temp`"
            :curComp="comp"
            :data="comp.data"
          />
          <i class="el-icon-delete-solid" @mousedown.stop @click.stop="delFormItem(comp, index)" :style="{ color: themeColor, borderColor: themeColor }" />
        </div>
      </VueDraggable>
    </van-form>
    <!-- 画板右键 -->
    <SeniorFormContextPanel
      v-if="showSeniorFormPanelContext"
      v-bind="contextConfig"
      :curComp="curComp"
      :id="`wft-senior-form-${curComp.id}`"
    />
    <!-- 文字提示 -->
    <div class="senior-form-tip" v-show="!curComp.config.isEnchase && !curComp.children.length">
      <p>双击切换状态</p>
      <p>盛放表单控件</p>
    </div>
  </div>
</template>
<script>
import { deepClone, getUuid } from '../../../utils'
import SeniorFormContextPanel from './seniorFormContext.vue'
import Bus from '../../../utils/bus'
import { VueDraggable } from 'vue-draggable-plus'
import themeMixin from '@/mixins/theme'
import useAttrsMixin from '../../../mixins/useAttrs'
export default {
  name: 'seniorForm',
  mixins: [themeMixin, useAttrsMixin],
  data() {
    return {
      contextConfig: {
        top: 0,
        left: 0,
        right: 'none',
        bottom: 'none'
      },
      showSeniorFormPanelContext: false,
      timer: null,
      idGlobal: 1000  // 用于生成随机字段使用
    }
  },
  components: { SeniorFormContextPanel, VueDraggable },
  props: {
    curComp: {
      type: Object,
      required: true
    }
  },
  watch: {
    'curComp.children': {
      handler() {
        this.$nextTick(() => {
          if(this.timer) {
            clearTimeout(this.timer)
            this.timer = null
          }
          this.timer = setTimeout(() => {
            this.initData()
          }, 200)
        })
      },
      deep: true
    }
  },
  mounted() {
    Bus.$on('hideSeniorFormPanelContext', this.hideSeniorFormPanelContext)
  },
  beforeDestroy() {
    Bus.$off('hideSeniorFormPanelContext', this.hideSeniorFormPanelContext)
    if(this.timer) {
      clearTimeout(this.timer)
      this.timer = null
    }
  },
  methods: {
    // 表单控件点击
    formItemClick(comp) {
      this.curComp.children.forEach(item => item.config.isActive = false)
      comp.config.isActive = true
      this.$emit('onActivated', comp)
    },
    // 删除表单控件
    delFormItem(comp, index) {
      const isActive = comp.config.isActive
      this.curComp.children.splice(index, 1)
      if(!isActive || !this.curComp.children.length) return
      if(index == this.curComp.children.length) {
        let activeComp = this.curComp.children[index - 1]
        activeComp.config.isActive = true
        this.$emit('onActivated', activeComp)
      } else {
        let activeComp = this.curComp.children[index]
        activeComp.config.isActive = true
        this.$emit('onActivated', activeComp)
      }
    },
    // 表单控件失活
    deactivatedFormItem() {
      this.curComp.children.forEach(item => item.config.isActive = false)
    },
    // 容器右键
    seniorFormContextHandler(event) {
      if(this.curComp.config.isEnchase) {
        event.stopPropagation()
        event.preventDefault()
        this.hideSeniorFormPanelContext()
        this.initContextPosition(event)
        this.showSeniorFormPanelContext = true
      }
    },
    // 隐藏右键面板
    hideSeniorFormPanelContext() {
      this.showSeniorFormPanelContext = false
    },
    // 初始化右键面板位置
    initContextPosition(event) {
      const { left, top } = document.getElementById(`wft-senior-form-${this.curComp.id}`).getBoundingClientRect()
      this.contextConfig.top = event.clientY - top
      this.contextConfig.left = event.clientX - left
      this.contextConfig.right = 'none'
      this.contextConfig.bottom = 'none'
    },
    // 初始化容器组件数据
    initData() {
      this.curComp.data = {}
      if(this.curComp.children && this.curComp.children.length) {
        this.curComp.children.forEach(item => {
          this.curComp.data[item.field] = item.data.data
        })
      }
    },
    // 双击可以拖动进来
    seniorFormDblclick() {
      this.curComp.config.isEnchase = !this.curComp.config.isEnchase
      this.curComp.config.draggable = !this.curComp.config.isEnchase
      this.curComp.config.resizable = !this.curComp.config.isEnchase
      if(this.curComp.config.isEnchase) {
        this.startEvent()
      } else {
        this.clearEvent()
      }
    },
    // 监听事件
    startEvent() {
      const seniorForm = document.getElementById(`wft-senior-form-${this.curComp.id}`)
      seniorForm.addEventListener('dragover', this.compDragover)
      seniorForm.addEventListener('drop', this.compDrop)
    },
    // 清除事件
    clearEvent() {
      const seniorForm = document.getElementById(`wft-senior-form-${this.curComp.id}`)
      seniorForm.removeEventListener('dragover', this.compDragover)
      seniorForm.removeEventListener('drop', this.compDrop)
    },
    compDragover(e) {
      e.preventDefault()
    },
    // 松开拖拽组件
    compDrop(event) {
      if(!event.dataTransfer?.getData('dragData')) return
      const dragData = JSON.parse(event.dataTransfer.getData('dragData'))
      if(dragData.curCom.type !== 'form') {
        return this.$message.warning('表单容器只能嵌套表单组件！')
      }
      const curCom = deepClone(dragData.curCom)
      curCom.id = getUuid()
      curCom.config.isActive = true
      curCom.parentId = this.curComp.id
      curCom.parentCompKey = this.curComp.compKey
      curCom.field = curCom.compKey + 'Field' + this.idGlobal++
      this.curComp.children?.forEach(item => item.config.isActive = false)
      this.curComp.children?.push(curCom)
      this.$emit('onActivated', curCom)
      Bus.$emit('addStack')
      Bus.$emit('startEventKeydown')
      if(event.dataTransfer?.getData('dragData')) {
        event.dataTransfer.clearData('dragData')
      }
    }
  }
}
</script>
<style scoped>
.wft-senior-form {
  width: 100%;
  height: 100%;
  padding: 2px;
  box-sizing: border-box;
  overflow: hidden;
}

.senior-form-tip {
  width: 100%;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 14px;
  color: #999;
  text-align: center
}

.senior-form-tip p {
  margin-top: 3px;
}

.wft-loop-glowing {
  box-shadow: 0 0 0 #d3e3fd, 0 0 10px #d3e3fd, 0 0 10px #d3e3fd, 0 0 30px #d3e3fd;
  cursor: auto;
}

.form-item {
  width: 100%;
  height: 50px;
  border: 1px dashed #e2e0e0;
  margin-bottom: 3px;
  cursor: move;
  box-sizing: border-box;
  position: relative;
  transition: border-color .3s;
}

.form-item:hover {
  border-color: #03a9f4;
}

.form-item:hover .el-icon-delete-solid {
  opacity: 1;
}

.form-item .el-icon-delete-solid {
  position: absolute;
  font-size: 15px;
  color: #086d6d;
  right: 6px;
  top: 50%;
  transform: translateY(-50%);
  opacity: 0;
  transition: opacity .3s;
  border: 1px solid #086d6d;
  border-radius: 50%;
  padding: 3px;
  cursor: pointer;
  z-index: 999;
}

.activeItem {
  border: 1px solid #03a9f4;
}
</style>
